var arguments = process.argv.splice(2);
var param1 = arguments[0];
// console.log('param1:', param1)

//将字符串转化为json
const str2json = function(srcStr) {
	let json = JSON.parse(srcStr); // (new Function("return " + srcStr))(); // eval('(' + srcStr + ')'); // 
	return json;
}

//-----------------------------------------------------------------------------------------------------

//获取json长度
const getJsonLength = function (jsonData) {
    //return Object.keys(jsonData).length;
    var jsonLength = 0;
    for (var item in jsonData) {
        jsonLength++;
    }
    return jsonLength;
}

//获取类型
const getType = function (data) {
    if (0 == data.questionType && 2 == data.type) {//分页节点，和微软forms一样处理成占位题
        return "占位题";
    }
    if (1 == data.questionType) {
        if (7 == data.selector) {//随机数题，产生1~1000的随机数，只显示，人无法作答，提交的answerContent为该随机数
        }
        return "填空";

    } else if (2 == data.questionType) {
        if (1 == data.selector) {
            return "单选";
        } else if (2 == data.selector) {
            return "多选";
        } else if (3 == data.selector) {
            return "下拉选项";
        }
    } else if (3 == data.questionType) {//图文说明题，由于不具有填写时"文本框"属性--只显示，只能编辑时有此属性故而标记为占位；提交的answerContent为1
        return "占位题";
    } else if (4 == data.questionType) {
        if (1 == data.subSelector) {
            return "矩阵单选";
        } else if (2 == data.subSelector) {
            return "矩阵多选";
        } else {
            return "矩阵量表-未知";
        }
    } else if (5 == data.questionType) {
        let choicesNum = data.choices.length;
        if (choicesNum > 1) { // 矩阵滑动（多个滑动）
            return "矩阵滑动";
        } else {//单个滑动
            return "滑动条";
        }
    } else if (6 == data.questionType) {
        return "排序选择";
    } else if (7 == data.questionType) {//暂未见过
        return "cbcMatrix";
    } else if (8 == data.questionType) {//暂未见过
        return "cbcChoice";
    } else if (9 == data.questionType) {//"街道地址";//比如城市街道地址选择，可归为级联下拉，也可简单归为下拉选项
        return "填空";
    } else if (10 == data.questionType) {
        if (!data.hasOwnProperty("answers")) {
            return "未知矩阵";
        }
        if (1 == data.answers[0].colType) {
            return "矩阵填空";
        } else if (2 == data.answers[0].colType) {
            return "矩阵单选";
        } else if (4 == data.answers[0].colType) {//矩阵下拉框
            return "未知矩阵";
        }
    } else if (11 == data.questionType) {
        //if(1==data.selector) {
        //    return "Scale";//可选中R角矩形框
        //} else if(2==data.selector) {
        //    return "NPS";//常用量表
        //}
        return "量表";
    } else if (12 == data.questionType) {
        if (1 == data.selector) {
            return "文件上传";
        } else if (2 == data.selector) {
            return "手写签名";
        } else if (3 == data.selector) {
            return "录音";
        }
    } else if (15 == data.questionType) {//"级联下拉";//也可简单归为下拉选项或填空
        return "填空";
    } else if (16 == data.questionType) {//即累加计数
        return "恒定总和";
    } else if (18 == data.questionType) {//可用鼠标对图进行下标记
        return "热力图";
    } else if (20 == data.questionType) {//多项填空
        return "填空";
    } else if (22 == data.questionType) {//分类题
        return "分类题";
    } else {
        return "未知";
    }
}

//构建矩阵选项数据
const buildMatrixData = function (inner, preTitle, oneChoice, answers) {
    var answersLength = getJsonLength(answers);
    //let tmpArr = new Array();
    for (var i = 0; i < answersLength; i++) {
        let tmpObj = new Object();
        const val = i + 1; //answers[i].sortNo; //answerNo;
        //tmpObj.title = preTitle + "_" + answers[i].display.replace(/<p>/g, "").replace(/<\/p>/g, "").replace(/<br>/g, "").replace(/_/g, "").replace(/\t/g, "") + "_" + val;
        tmpObj.title = preTitle + "_" + answers[i].answerId + "_" + answers[i].display;//格式：行名_列id_列名
        tmpObj.optionId = oneChoice.choiceId + "_" + answers[i].answerId + "_" + val;//格式：行ID_列ID_序号
        tmpObj.value = val;
        inner.push(tmpObj);//tmpArr.push(tmpObj);
    }
    // tmpArr.sort((a,b)=>{ //按value排序
    //     return a.value - b.value
    // });
    // let tmpArrLength = getJsonLength(tmpArr);
    // for(let i = 0; i<tmpArrLength; i++){
    //     tmpArr[i].value = i+1;
    // }
    // inner.push(...tmpArr); //合并到inner数组
}

//获取选项
const getOptions = function (data) {
    var inner = new Array();
    var optionsLength = getJsonLength(data.choices);
    for (var i = 0; i < optionsLength; i++) {
        let tmpObj = new Object();
        let isMatrix = false;

        var choiceTitle = data.choices[i].display.replace(/<p>/g, "").replace(/<\/p>/g, "").replace(/<br>/g, "").replace(/_/g, "");
        switch (data.questionType) {
            case 2://选择类（包含单选，多选，下拉选）
                if (data.choices[i].hasOwnProperty("extend")) {
                    tmpObj.title = choiceTitle + "|underline";
                } else {
                    tmpObj.title = choiceTitle;
                }
                tmpObj.optionId = data.choices[i].choiceId.toString();
                break;
            case 5://滑动条
                let choicesNum = data.choices.length;
                let minVal = data.validation.min;
                let maxVal = data.validation.max;
                if (choicesNum > 1) { // 矩阵滑动（多个滑动）
                    tmpObj.title = choiceTitle + "_" + minVal + "_" + maxVal;
                } else {//单个滑动
                    tmpObj.title = choiceTitle;
                }
                tmpObj.optionId = data.choices[i].choiceId.toString();
                break;
            case 6://排序
            case 11://量表
            case 16://恒定总和
                tmpObj.title = choiceTitle;
                tmpObj.optionId = data.choices[i].choiceId.toString();
                break;
            case 4://矩阵量表
            case 10://矩阵相关
                if (!data.hasOwnProperty("answers")) {
                    break;
                }
                var preTitle = choiceTitle;
                var stopIdx = choiceTitle.indexOf("||");
                if (-1 != stopIdx) {
                    preTitle = choiceTitle.substring(0, stopIdx);
                }
                buildMatrixData(inner, preTitle, data.choices[i], data.answers);
                isMatrix = true;
                break;
            // case 15://级联题（更趋向于填空？）
            //     tmpObj.title = data.expand.content.optionData.title; 
            //     tmpObj.optionId = null; 
            //     break;
            default:
                break;
        }
        //tmpObj.title = data.choices[i].display; // 选项标题：注意， ‘_’ 符号有特殊用途， ‘|underline’表示选项有填空 。若为矩阵题使用 “主标题_分值_打分标题”的格式
        //tmpObj.optionId = data.choices[i].choiceId; // 选项id，提交用                    
        tmpObj.value = data.choices[i].choiceNo; // 选项对应的分值（打分使用，若无特殊定义，可以赋值-1.），当前用于relation选项特殊用途
        if (false == isMatrix) {
            inner.push(tmpObj);
        }
    }
    return inner;
}

//当前为未选定则将其他选项设为选定
const setData2OtherOption = function (data, jumpData, dstId, choiceLocator) {
    var choiseLength = getJsonLength(data.choices);
    for (var i = 0; i < choiseLength; i++) {
        if (data.choices[i].choiceNo == choiceLocator) {
            continue;
        }
        let jmpObj = new Object();
        jmpObj.condition = 1;
        jmpObj.destId = dstId;
        jmpObj.optionId = data.choices[i].choiceId.toString();
        jumpData.push(jmpObj);
    }
}

//获取跳题数据
const getJumpData = function (data, type) {
    var jumpData = new Array()
    var slLength = getJsonLength(data.skipLogic);
    for (var i = 0; i < slLength; i++) {
        let cond = data.skipLogic[i].condition;//跳转条件：1选定；2未选定
        let dstId = data.skipLogic[i].skipToDestination.toString(); // 跳转的id。跳到结束赋值'-1'或'0';
        if (2 == cond && ("单选" == type || "下拉选项" == type)) {//如果当前为“未选定”且为单选或下拉选，则将其他选项设为选定
            setData2OtherOption(data, jumpData, dstId, data.skipLogic[i].choiceLocator);
        } else if ('量表' == type) {//量表有跳题暂时不支持，临时处理为设置类型为：量表跳题
            let jmpObj = new Object();
            jmpObj.condition = cond;
            jmpObj.destId = dstId;
            jmpObj.optionId = '量表跳题';
            jumpData.push(jmpObj);
        } else if ('ENDOFERROR' == dstId) {//检测题，选中choiceLocator对应的则检测通过 无跳转继续作答，设置其他项选中跳转到结束答题；
            setData2OtherOption(data, jumpData, dstId, data.skipLogic[i].choiceLocator);
        } else {//选定
            let jmpObj = new Object();
            jmpObj.condition = cond;
            jmpObj.destId = dstId;
            jmpObj.optionId = getJumpOptionId(data, data.skipLogic[i].choiceLocator); // 选中选项id，选中才跳转。
            jumpData.push(jmpObj);
        }
    }
    return jumpData;
}

//获取跳题的选中选项id
const getJumpOptionId = function (data, choiceLocator) {
    var choiseLength = getJsonLength(data.choices);
    for (var i = 0; i < choiseLength; i++) {
        if (data.choices[i].choiceNo == choiceLocator) {
            return data.choices[i].choiceId.toString();
        }
    }
}

//获取 destId
const getDstId = function (dstId) {
    if (undefined == dstId || null == dstId) {
        return dstId;
    }
    return dstId.toString();
}

//更新跳转逻辑题号
const updateSkipLogic = function (logicDict4skip, dataArray, blockJumpDick) {
    let jsonLen = getJsonLength(dataArray);
    for (let i = 0; i < jsonLen; i++) {
        if (dataArray[i].hasJump) {//跳转逻辑题
            let jumpDataLen = getJsonLength(dataArray[i].jumpData);
            let tmpUnselected = null;
            for (let j = 0; j < jumpDataLen; j++) {
                let questionId = dataArray[i].jumpData[j].destId;
                dataArray[i].jumpData[j].destId = getDstId(logicDict4skip[questionId]);
                //destId没有包含3种情况：
                //1.ENDOFBLOCK代表当前块结束，赋值下一个块的第一道题；
                //2.ENDOFSURVEY代表整个问卷结束，赋值'-1'；
                //3.ENDOFERROR代表如果没有通过验证，会结束问卷并提交（赋值'-1'）；如果通过验证则继续答下一题
                if (null == dataArray[i].jumpData[j].destId) {
                    if ('ENDOFBLOCK' == questionId) {
                        dataArray[i].jumpData[j].destId = blockJumpDick[dataArray[i].qid];
                    } else if ('ENDOFSURVEY' == questionId) {
                        dataArray[i].jumpData[j].destId = '-1';
                    } else if ('ENDOFERROR' == questionId) {//前面获取跳题数据中已设置其他项数据（类似未选定），这里改为结束问卷就行
                        dataArray[i].jumpData[j].destId = '-1';
                    } else {//未知的，这里都作问卷出错处理
                        dataArray[i].jumpData[j].destId = 'error';
                    }
                }

                // 单选或下拉包含"未选定"，后续选项 保持和它一致
                if (null != tmpUnselected) {
                    dataArray[i].jumpData[j] = tmpUnselected;
                }
                //处理逻辑：若是多选且包含"未选定"则返回NOT_SUPPORT；若是单选或下拉包含"未选定"，则该题后面的逻辑都按此未选定跳转
                if (-1 != dataArray[i].type.indexOf("多选") && 2 == dataArray[i].jumpData[j].condition) {
                    dataArray[i].jumpData[j].destId = "NOT_SUPPORT";
                } else if (-1 != dataArray[i].type.indexOf("单选") || -1 != dataArray[i].type.indexOf("下拉")) {
                    if (2 == dataArray[i].jumpData[j].condition) {//未选定
                        tmpUnselected = dataArray[i].jumpData[j];
                    }
                }
                delete dataArray[i].jumpData[j].condition; //移除跳转条件属性
            }
        }
    }
}

//更新显示逻辑题号
const updateDisplayLogic = function (logicDict4display, dataArray) {
    let jsonLen = getJsonLength(dataArray);
    let topicDict = { 1: "|", 2: "$" };//根据框架依照问卷星规则：逻辑与用|，逻辑或用$
    let optionDict = { 1: ".", 2: ";" };
    let operDict = { 1: "", 2: "-" }
    for (let i = 0; i < jsonLen; i++) {
        if (!dataArray[i].hasOwnProperty("relation") || '' == dataArray[i].relation) {//显示逻辑题才可往后运行
            continue;
        }
        let result = "";
        let retDict = [];
        let displayLogicArr = dataArray[i].relation;
        let displayLogicLen = getJsonLength(displayLogicArr);
        let firstKey = null;
        for (let k = 0; k < displayLogicLen; k++) {
            let sourceQuestionId = displayLogicArr[k].sourceQuestionId;
            let conjuction = displayLogicArr[k].conjuction;//逻辑连词，逻辑操作 1与 2或
            let operator = displayLogicArr[k].operator;//1选定；2未选定
            let topicNo = logicDict4display[sourceQuestionId] + "";//题号
            let choice = displayLogicArr[k].choiceLocator;

            if (0 == k) {//第一个不加逻辑连词
                retDict[topicNo] = topicNo + "," + operDict[operator] + choice;
                firstKey = topicNo;
            } else {
                if (undefined == retDict[topicNo]) {//没有出现过该题号
                    retDict[topicNo] = topicDict[conjuction] + topicNo + "," + operDict[operator] + choice;
                } else {//出现过该题号，则拼接题项
                    let tmp = retDict[topicNo];
                    retDict[topicNo] = tmp + optionDict[conjuction] + operDict[operator] + choice;
                }
            }
        }
        for (let key in retDict) {
            if (key != firstKey) {
                result = result + retDict[key];
            } else {
                result = retDict[key] + result;
            }
        }
        dataArray[i].relation = result;
    }
}

//情景题构建
const buildScene = function () { // deprecated
    let tmp = new Object();
    tmp.id = 0;
    tmp.qid = '';
    tmp.range = null;
    tmp.relation = '';
    tmp.inner = null;
    tmp.isRequired = true;
    tmp.title = '';
    tmp.hasJump = false;
    tmp.jumpData = null;

    tmp.type = "情景题";
    return tmp;
}

//获取场景题(也叫随机题)BlockIds数组
const getSceneBlockIdArr = function (secondFlowList) {
    let sceneBlockIdArr = new Array();
    for (let i = 0; i < secondFlowList.length; i++) {
        sceneBlockIdArr.push(secondFlowList[i].blockId);
    }
    return sceneBlockIdArr;
}

// 获取系统类型
const traslateType = function (type, srcType) {
    if ("单选" == type) {
        return "SINGLE";
    } else if ("多选" == type) {
        return "MULTIPLE";
    } else if ("下拉选项" == type) {
        return "SINGLE_SELECT";
    } else if ("排序选择" == type) {
        return "SORTED";
    } else if ("量表" == type) {
        return "SCALE";
    } else if ("矩阵单选" == type | "矩阵量表" == type) {
        return "MATRIX";
    } else if ("矩阵多选" == type) {
        return "MULTIPLE_MATRIX";
    } else if ("滑动条" == type) {
        return "SINGLE_SLIDE";
    } else if ("矩阵滑动" == type) {
        return "SLIDE";
    } else if ("比重" == type) {
        return "RATE";
    } else if ("填空" == type) {
        if ("1_1_5_0" == srcType) {//日期题
            return "DATE";
            // } else if() {//地区题
            //     return "AREA";
        } else if ("1_20_1_0" == srcType) {//"多项填空"
            return "MULTIPLE_TEXT";
        } else if (srcType.startsWith("1_15_")) {//级联题
            return "CASCADE_DROPDOWN";
        } else if (srcType.startsWith("1_9_")) {//第二种级联题
            return "CASCADE_DROPDOWN";
        } else {
            return "TEXT";
        }
    } else if ("矩阵填空" == type) {
        return "MATRIX_TEXT";
    } else if ("占位题" == type) {
        return "DESCRIPTION";
    } else {
        return type;
    }
}

// 转译是否必须：0代表非必填；1代表必填
const traslateRequired = function (isReq) {
    if (isReq) { //必填
        return '1';
    }
    return '0';
}

// 判断是否为填空类题型
const isText = function (curQst) {
    if ("TEXT" == curQst.sys_type || "DATE" == curQst.sys_type || "MULTIPLE_TEXT" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {
        return true;
    }
    return false;
}

// 设置最大最小值，如果存在的话
const setMaxAndMinIfExist = function (curQst, range) {
    if("SCALE" == curQst.sys_type) { //量表不设置max和min
        return;
    }
    if (undefined == range || null == range) {
        return;
    }
    curQst.min_oper_num = range.minvalue;
    curQst.max_oper_num = range.maxvalue;
}

// 设置选项维度跳题逻辑，如果存在的话
const setJumpOnOptIfExist = function(curQst, option, jumpDict) {
    let optVal = jumpDict[option.value];
    if(curQst.is_jump && undefined != optVal) {
        option.is_jump = true; // 是否跳题
        option.jump_to = optVal; // 跳到第几题
    }
}

// 获取option的is_text字段值
const getOptionIsText = function (curQst, optName) {
    if ("SINGLE" == curQst.sys_type || "MULTIPLE" == curQst.sys_type) {
        if(optName.endsWith('|underline')) {
            return 1;//return true; //问卷星里竟然是数字1，无填空是返回false
        }
    }
    return curQst.is_text; 
}

// 转译选项
const tanslateOptions = function (optionList, curQst, srcQstData, dataIndexDict, jumpDict) {
    let optArr = new Array();
    let len = getJsonLength(optionList);
    //{"lastDataIndex" : 0, "curQstDataIndex":[]};
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = optionList[i].title; // 题目的选项名称
        option.value = (i+1).toString(); // 题目的选项值
        option.real_value = optionList[i].optionId; // 问卷提交对应的值

        option.title = curQst.title + option.name; // 改成和问卷星解析一样：题目标题+选项名称
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        setJumpOnOptIfExist(curQst, option, jumpDict); //设置选项维度跳题逻辑，如果存在的话

        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = getOptionIsText(curQst, option.name); // 是否需要填空
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = curQst.min_oper_num; // 最小值
        option.max_oper_num = curQst.max_oper_num; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵or多填
        if ("MULTIPLE" == curQst.sys_type || "SORTED" == curQst.sys_type) {//多选每个选项都要有索引
            option.data_index = lastDataIndex + i; // 数据库索引
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        } else {
            option.data_index = lastDataIndex; // 数据库索引
        }
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
    }
    if ("MULTIPLE" == curQst.sys_type || "SORTED" == curQst.sys_type) {
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    } else if("DESCRIPTION" == curQst.sys_type) {
        //描述类占位题不生成dataIndexDict值
    } else {
        dataIndexDict["curQstDataIndex"].push(lastDataIndex);
        dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    }
    return optArr;
}

// 构建填空option
const buildTextOption = function (curQst, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = ""; // 题目的选项名称
    option.value = "1";
    option.real_value = ""; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = []; // 选项
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 获取矩阵多选的子节点选项
const getChildOptionOnly4MultiMatrix = function(len, curQst, oldData, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let optArr = new Array();
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + oldData.srcQstData.answers[i].display; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = oldData.srcQstData.answers[i].display; // 题目的选项名称
        option.value = (i+1).toString(); // 题目的选项值
        option.real_value = oldData.srcQstData.answers[i].answerId; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = lastDataIndex + i; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
    }
    dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    return optArr;
}

// 获取子节点选项（只针对矩阵or多填）
const getChildOption = function (maxNum, curQst, oldData) {
    let optArr = new Array();
    if ("MULTIPLE_TEXT" == curQst.sys_type || "SLIDE" == curQst.sys_type || "SINGLE_SLIDE" == curQst.sys_type) { // 多项填空or矩阵滑动条或滑动条
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title; // 父题目
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = curQst.name; // 题目的选项名称
        option.value = curQst.value;
        option.real_value = curQst.real_value; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = curQst.min_oper_num; // 最小值
        option.max_oper_num = curQst.max_oper_num; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = curQst.data_index; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        return optArr;
    }
    if (undefined == maxNum || null == maxNum) {
        return optArr;
    }
    for (let i = 0; i < maxNum; i++) {//矩阵单选，矩阵量表，矩阵多选，矩阵填空
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + oldData.srcQstData.answers[i].display; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = oldData.srcQstData.answers[i].display; // 题目的选项名称
        option.value = (i+1).toString();
        option.real_value = oldData.srcQstData.answers[i].answerId; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = curQst.data_index; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
    }
    return optArr;
}

// 获取子选项（只针对矩阵or多填）
const getChildren = function (oldData, curQst, dataIndexDict) {
    let optionList = oldData.inner;
    let range = oldData.range;
    let childArr = new Array();

    //{"lastDataIndex" : 0, "curQstDataIndex":[]};
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let len = 0;
    if ("MATRIX" == curQst.sys_type || "MULTIPLE_MATRIX" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {//矩阵单选，矩阵量表，矩阵多选，矩阵填空
        len = getJsonLength(oldData.srcQstData.choices);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + oldData.srcQstData.choices[i].display; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = oldData.srcQstData.choices[i].display; // 题目的选项名称
            curChild.value = (i+1).toString();
            curChild.real_value = oldData.srcQstData.choices[i].choiceId; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = false; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            if("MULTIPLE_MATRIX" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {//矩阵多选or矩阵填空
                curChild.options = getChildOptionOnly4MultiMatrix(getJsonLength(oldData.srcQstData.answers), curChild, oldData, dataIndexDict); // 选项
                curChild.data_index = dataIndexDict["lastDataIndex"]; // 数据库索引
                dataIndexDict["curQstDataIndex"].push(dataIndexDict["lastDataIndex"]);
                dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + 1;
            } else {
                curChild.data_index = dataIndexDict["lastDataIndex"] + i; // 数据库索引
                dataIndexDict["curQstDataIndex"].push(dataIndexDict["lastDataIndex"] + i);
                curChild.options = getChildOption(getJsonLength(oldData.srcQstData.answers), curChild, oldData); // 选项
            }
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
        }
        if("MULTIPLE_MATRIX" != curQst.sys_type) {//不是矩阵多选
            dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + len;
        }
    } else if("MULTIPLE_TEXT" == curQst.sys_type) {//多项填空
        len = getJsonLength(oldData.srcQstData.choices);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + oldData.srcQstData.choices[i].display; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = oldData.srcQstData.choices[i].display; // 题目的选项名称
            curChild.value = (i+1).toString();
            curChild.real_value = oldData.srcQstData.choices[i].choiceId; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = curQst.is_text; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            curChild.options = getChildOption(getJsonLength(oldData.srcQstData.answers), curChild, oldData); // 选项
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        }
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    } else {
        len = getJsonLength(optionList);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + optionList[i].title == undefined? "": optionList[i].title; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = optionList[i].title.split("_")[0]; // 题目的选项名称
            curChild.value = (i+1).toString();
            curChild.real_value = optionList[i].optionId; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = curQst.is_text; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            curChild.options = getChildOption((range == undefined || range == null) ? null : range.maxvalue, curChild, oldData); // 选项
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        }
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    }
    return childArr;
}

// 获取data_index数据中的多选选项
const getDataIdxCheckboxOption = function (curQst, dataIndexDict, idx) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = curQst.name; // 题目的选项名称
    option.value = idx+1;
    option.real_value = curQst.value; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = []; // 选项
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 获取data_index数据
const getDataIndexArr = function (result) {
    let dataIndexArr = new Array(); // 数据库对应的数据

    let counter = 0;
    let dataArr = result.data; // new Array();//
    let len = getJsonLength(dataArr);
    let dataIndexDict = { "lastDataIndex": 0, "curQstDataIndex": [] };//用于记录上一个索引，和当前题目data_index集合
    for (let i = 0; i < len; i++) {
        //console.log(key);
        // if ("多选" == dataArr[i].type) {
        //     let optionList = dataArr[i].inner;
        //     let len = getJsonLength(optionList);
        //     for (let j = 0; j < len; j++) {
        //         let curData = dataArr[i];
        //         let tmp = new Object();
        //         tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        //         tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        //         tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        //         tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        //         tmp.sys_type = traslateType(curData.type, curData.srcType); // 内部平台题目类型
        //         tmp.name = tmp.title; // 题目名称，同title
        //         tmp.value = ""; // 值 - 题目维度下不需要填
        //         tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        //         tmp.jump_to = null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        //         tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        //         tmp.is_text = isText(tmp); // 是否填空题 bool
        //         tmp.relation = curData.relation;
        //         tmp.min_oper_num = 0; // 最小值
        //         tmp.max_oper_num = 0; // 最大值
        //         setMaxAndMinIfExist(tmp, curData.range);
        //         tmp.rate = 0; // 权重 - 题目维度下不需要填
        //         tmp.text = ""; // 填空内容 - 题目维度下不需要填
        //         tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        //         tmp.options = [getDataIdxCheckboxOption(tmp, dataIndexDict, j)];
        //         tmp.children = [];
        //         tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        //         dataIndexDict["curQstDataIndex"] = [];

        //         dataIndexArr.push(tmp);
        //     }
        // } else {
        let jumpDict = {};
        let curData = dataArr[i];
        let tmp = new Object();
        tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        tmp.sys_type = traslateType(curData.type, curData.srcType); // 内部平台题目类型
        tmp.name = tmp.title; // 题目名称，同title
        tmp.value = ""; // 值 - 题目维度下不需要填
        tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        if(curData.hasJump) {
            jumpDict = translate2JumpDict(curData.jumpData);
        }
        tmp.jump_to = "";//null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        tmp.is_text = isText(tmp); // 是否填空题 bool
        tmp.relation = curData.relation;
        tmp.min_oper_num = 0; // 最小值
        tmp.max_oper_num = 0; // 最大值
        setMaxAndMinIfExist(tmp, curData.range);
        tmp.rate = 0; // 权重 - 题目维度下不需要填
        tmp.text = ""; // 填空内容 - 题目维度下不需要填
        tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        tmp.options = [];
        tmp.children = [];
        if ("MATRIX" == tmp.sys_type || "MULTIPLE_MATRIX" == tmp.sys_type || "MATRIX_TEXT" == tmp.sys_type
            || "MULTIPLE_TEXT" == tmp.sys_type || "SLIDE" == tmp.sys_type) { // 矩阵or多填题or滑动条
            tmp.children = getChildren(curData, tmp, dataIndexDict);
        } else if ("TEXT" == tmp.sys_type || "AREA" == tmp.sys_type || "DATE" == tmp.sys_type) { // 填空类题型
            tmp.options.push(buildTextOption(tmp, dataIndexDict));
        } else {
            tmp.options = tanslateOptions(curData.inner, tmp, curData.srcQstData, dataIndexDict, jumpDict); // 选项
        }
        tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        tmp.is_repeat = false; // 是否去重 - 题目维度下不需要填 - 对于解析来说，默认false
        dataIndexDict["curQstDataIndex"] = [];

        dataIndexArr.push(tmp);
        // }
    }
    let newDataIndexArr = convertDataIndexArr(dataIndexArr); // 转换data_index数组为wjx格式
    return newDataIndexArr;//dataIndexArr;
}

// 转换data_index数组为wjx格式
const convertDataIndexArr = function (dataIndexArr) {
    let newDataIndexArr = new Array();
    let len = getJsonLength(dataIndexArr);
    counter = 0;
    for (let i = 0; i < len; i++) {
        let curData = dataIndexArr[i];
        if ("MULTIPLE_MATRIX" == curData.sys_type ) {// 矩阵多选：拆children中的options，但option值取原来整体options
            for (let j = 0; j < curData.children.length; j++) {//遍历children
                let child = curData.children[j];
                let options = child.options;
                let optStr = JSON.stringify(options);
                for (let k = 0; k < options.length; k++) {
                    let newTmp = options[k];
                    newTmp.index = counter++;
                    newTmp.options = JSON.parse(optStr);
                    newDataIndexArr.push(newTmp);
                }
            }
        } else if ("MATRIX_TEXT" == curData.sys_type) {// 矩阵填空：拆children中的options
            curData.children.forEach(child => {
                child.options.forEach(option => {                        
                    let newTmp = option;
                    newTmp.index = counter++;
                    newTmp.options = [JSON.parse(JSON.stringify(option))];
                    newDataIndexArr.push(newTmp);
                });                    
            });
        } else if ("SINGLE_SLIDE" == curData.sys_type) {// 单选滑动条：拆options，但title和name取原来整体title和name
            curData.children.forEach(child => {
                let newTmp = child;
                newTmp.title = curData.title;
                newTmp.name = curData.name;
                newTmp.index = counter++;
                newDataIndexArr.push(newTmp);
            });
        } else if ("MATRIX" == curData.sys_type || "MULTIPLE_TEXT" == curData.sys_type || "SLIDE" == curData.sys_type ) { // 矩阵or多填题：拆children
            curData.children.forEach(child => {
                let newTmp = child;
                newTmp.index = counter++;
                newDataIndexArr.push(newTmp);
            });
        } else if ("MULTIPLE" == curData.sys_type || "SORTED" == curData.sys_type || "RATE" == curData.sys_type ) { // 多选，排序和比重题：拆options
            curData.options.forEach(option => {
                let newTmp = option;
                newTmp.index = counter++;
                newTmp.options = [JSON.parse(JSON.stringify(option))];
                newDataIndexArr.push(newTmp);
            });
        } else {
            let newTmp = curData;
            newTmp.index = counter++;
            newDataIndexArr.push(newTmp);
        }
    }
    return newDataIndexArr;
}

// 转换为jump字典
const translate2JumpDict = function (oldJumpData) {
    let jumpDict = {};
    let len  = getJsonLength(oldJumpData);
    for(let i=0; i<len; i++) {
        jumpDict[oldJumpData[i].optionId] = oldJumpData[i].destId;
    }
    return jumpDict;
}

// 将指定json数据中的real_value替换成rl_value
const modifyRealValueToRlValue = function (jsonData) {
    let len = getJsonLength(jsonData);
    const traverse = function (obj) {
        if (typeof obj !== 'object' || obj === null) {
            return;
        }
        for (let key in obj) {
            if (obj.hasOwnProperty('real_value')) {
                obj['rl_value'] = obj['real_value'];
                delete obj['real_value'];
            } else {
                traverse(obj[key]);
            }
        }
    };
    traverse(jsonData);
    return jsonData;
}

// 获取选项option的值列表
const getOptionsValueList = function (options) {
    let valueList = new Array();
    for (let i = 0; i < options.length; i++) {
        valueList.push(options[i].value);
    }
    return valueList;
}

// 获取选项option的范围值列表
const getOptionsRangeValueList = function (curData) {
    let valueList = new Array();
    let minVal = curData.min_oper_num;
    let maxVal = curData.max_oper_num;
    for (let i = minVal; i <= maxVal; i++) {
        valueList.push(i);
    }
    return valueList;
}

// 增加valid_values字段
const addValidValues = function (dataIndexArr) {
    let len = getJsonLength(dataIndexArr);
    let sortedQstList = new Array();// 排序题列表，由于其值分散需要收集到一起
    let sortedQstValueList = [-3, -2]; // 排序题值列表
    // 根据每道题的类型添加valid_values字段
    for (let i = 0; i < len; i++) {
        let curData = dataIndexArr[i];
        if ("SINGLE" == curData.sys_type) {// 单选题
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MULTIPLE" == curData.sys_type) {// 多选题
            curData.valid_values = [-3, -2, 0, 1];
        } else if ("SINGLE_SELECT" == curData.sys_type) {// 下拉选择
            curData.valid_values = [-3, -2].concat(getOptionsValueList(curData.options));
        } else if ("SORTED" == curData.sys_type) {// 排序题
            sortedQstList.push(curData);
            sortedQstValueList = sortedQstValueList.concat(getOptionsValueList(curData.options));
        } else if ("SCALE" == curData.sys_type) {// 量表题
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MATRIX" == curData.sys_type) {// 矩阵单选
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MULTIPLE_MATRIX" == curData.sys_type) {// 矩阵多选
            curData.valid_values = [-3, -2, 0, 1];
        } else if ("SINGLE_SLIDE" == curData.sys_type) {// 单项滑动题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("SLIDE" == curData.sys_type) {// 矩阵滑动题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("RATE" == curData.sys_type) {// 比重题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("DATE" == curData.sys_type) {// 日期题
            curData.valid_values = null;
        } else if ("AREA" == curData.sys_type) {// 地区题
            curData.valid_values = null;
        } else if ("TEXT" == curData.sys_type) {// 填空题
            curData.valid_values = null;
        } else if ("MULTIPLE_TEXT" == curData.sys_type) {// 多项填空
            curData.valid_values = null;
        } else if ("MATRIX_TEXT" == curData.sys_type) {// 矩阵填空
            curData.valid_values = null;
        } else {// DESCRIPTION描述类占位题
            curData.valid_values = null;
        }
    }
    // 处理排序题的valid_values字段
    for (let i = 0; i < sortedQstList.length; i++) {
        let curData = sortedQstList[i];
        curData.valid_values = sortedQstValueList;
    }
}

// 转换为新的结果
const translate2newResult = function (result, resultNew) {
    let listDataArr = new Array(); // 返回的题目内容列表
    let dataArr = result.data; // new Array();//
    let len = getJsonLength(dataArr);
    let dataIndexDict = { "lastDataIndex": 0, "curQstDataIndex": [] };//用于记录上一个索引，和当前题目data_index集合
    for (let i = 0; i < len; i++) {
        let jumpDict = {};
        let curData = dataArr[i];
        let tmp = new Object();
        tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        tmp.sys_type = traslateType(curData.type, curData.srcType); // 内部平台题目类型
        tmp.name = curData.title; // 题目名称，给制单人看的
        tmp.value = ""; // 值 - 题目维度下不需要填
        tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        if(curData.hasJump) {
            jumpDict = translate2JumpDict(curData.jumpData);
        }
        tmp.jump_to = "";//null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        tmp.is_text = isText(tmp); // 是否填空题 bool
        tmp.relation = curData.relation;
        tmp.min_oper_num = 0; // 最小值
        tmp.max_oper_num = 0; // 最大值
        setMaxAndMinIfExist(tmp, curData.range);
        tmp.rate = 0; // 权重 - 题目维度下不需要填
        tmp.text = ""; // 填空内容 - 题目维度下不需要填
        tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        tmp.options = [];
        tmp.children = [];
        if ("MATRIX" == tmp.sys_type || "MULTIPLE_MATRIX" == tmp.sys_type || "MATRIX_TEXT" == tmp.sys_type
            || "MULTIPLE_TEXT" == tmp.sys_type || "SLIDE" == tmp.sys_type) { // 矩阵or多填题or滑动条
            tmp.children = getChildren(curData, tmp, dataIndexDict);
        } else if ("TEXT" == tmp.sys_type || "AREA" == tmp.sys_type || "DATE" == tmp.sys_type) { // 填空类题型
            tmp.options.push(buildTextOption(tmp, dataIndexDict));
        } else {
            tmp.options = tanslateOptions(curData.inner, tmp, curData.srcQstData, dataIndexDict, jumpDict); // 选项
        }
        if("DESCRIPTION" != tmp.sys_type) {//描述类占位题不生成dataIndexDict值
            tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        }
        tmp.is_repeat = false; // 是否去重 - 题目维度下不需要填 - 对于解析来说，默认false
        dataIndexDict["curQstDataIndex"] = [];

        listDataArr.push(tmp);
    }
    resultNew.list = modifyRealValueToRlValue(listDataArr);//相关分析需要删除real_value才能运行成功，故此处先将real_value替换成rl_value
    let dataIndexArr = getDataIndexArr(result);
    let newDataIndexArr = modifyRealValueToRlValue(dataIndexArr); // 相关分析需要删除real_value才能运行成功，故此处先将real_value替换成rl_value
    addValidValues(newDataIndexArr); // 增加valid_values字段
    resultNew.data_index = newDataIndexArr;
    resultNew.total_data_index = dataIndexDict["lastDataIndex"];
}

const fs = require('fs');
// const srcData = window.qsSrcData;
//加载题目主体函数定义
const getDataArr = function (sdata_file) {
    // console.log("==================================== enter js ====================================");
    let sdata = "";
    try {
        const data = fs.readFileSync(sdata_file);
        // console.log(data.toString());
        sdata = data.toString();
    } catch (err) {
        console.error(err);
    }
    let srcData = str2json(sdata);
    let resultNew = { list: [], data_index: [], total_data_index: 0 };//list代表问卷的所有题目；data_index代表数据库对应的数据；

    var result = { title: '', error: '', data: [] };//error内容为加载失败消息：如问卷暂停、需微信登录等
    var dataArray = new Array(); // 返回的题目内容列表
    var logicDict4skip = []; //跳转逻辑映射字典{questionId:qstId}
    var logicDict4display = []; //显示逻辑映射字典{questionId:sortNo}
    var blockJumpDick = []; //跳转到下一个block的情况字典{源qid:下个block的第一题的qid}
    var blockNum = getJsonLength(srcData.blocks);
    var counter = 0;
    let sceneBlockIdArr = new Array();

    // 情景题(也叫随机题)临时处理方案：返回“情景题”暂时不做处理；
    let flList = srcData.surFlow.flowList;
    let flowLength = getJsonLength(flList);
    for (let i = 0; i < flowLength; i++) {
        if (0 == flList[i].blockId && 0 != flList[i].subSet) {
            sceneBlockIdArr.push(...getSceneBlockIdArr(flList[i].flowList));//合并数组
        }
    }

    // 流程控制暂不支持
    for (let i = 0; i < flowLength; i++) {
        if (flList[i].hasOwnProperty("branchLogicList")) {
            result.title = srcData.surveyName;
            result.error = "流程控制暂不支持";
            result.data = dataArray;
            return result;
        }
    }

    for (var k = 0; k < blockNum; k++) {
        var curBlock = srcData.blocks[k];
        // HBO块暂不支持处理
        if (5 == curBlock.type) {
            result.title = srcData.surveyName;
            result.error = "HBO块暂不支持(起始题号" + (++counter) + ")";
            result.data = dataArray;
            return result;
        }
        // CBC块暂不支持处理
        if (4 == curBlock.type) {
            result.title = srcData.surveyName;
            result.error = "CBC块暂不支持(起始题号" + (++counter) + ")";
            result.data = dataArray;
            return result;
        }
        var elements = curBlock.blockElements;
        var jsonLen = getJsonLength(elements);
        for (var i = 0; i < jsonLen; i++) {
            var tmp = new Object();
            tmp.id = ++counter; // 全局题号 ，从1开始递增。 
            tmp.qid = elements[i].qstId.toString(); // 题目id（提交使用的ID）
            tmp.type = getType(elements[i]);  // 见typeName 定义 返回字符串
            if (-1 != sceneBlockIdArr.indexOf(curBlock.blockId) || 2 == curBlock.blockOption.randomType) {//对于情景题的类型赋值
                tmp.type = "情景题";
            }
            tmp.range = null;
            tmp.relation = '';
            tmp.jumpData = null;
            tmp.inner = getOptions(elements[i]); // 选项数据。 见选项数据定义
            // 选项的可选范围（多选、排序赋值，单选等不用管）。
            if (elements[i].hasOwnProperty("validation")) {
                if (elements[i].validation.hasOwnProperty("min") && elements[i].validation.hasOwnProperty("max")) {
                    tmp.range = {//目前仅发现滑块题有这种范围
                        minvalue: elements[i].validation.min,
                        maxvalue: elements[i].validation.max
                    };
                }
            }
            if (elements[i].hasOwnProperty("displayLogic")) {
                tmp.relation = elements[i].displayLogic; //赋值关联项;见关联字符串定义
            }
            if (!elements[i].hasOwnProperty("setting")) {//存在无setting的情况
                tmp.isRequired = false;
            } else {
                tmp.isRequired = elements[i].setting.isForceResponse; // 是否必选。
            }

            tmp.title = elements[i].qstNo + elements[i].questionText.replace(/<p>/g, "").replace(/<\/p>/g, "").replace(/<br>/g, "").replace(/_/g, ""); // 题目标题，需要避免使用特殊字符“_”
            tmp.hasJump = elements[i].hasOwnProperty("skipLogic"); // 是否跳题。为跳题需要定义
            if (tmp.hasJump) {
                tmp.jumpData = getJumpData(elements[i], tmp.type); // 跳题数据，hasJump为true时赋值。见跳题数据定义
                //记录跳转到下一个block的情况
                if (k + 1 < blockNum) {
                    let tmpElemArr = srcData.blocks[k + 1].blockElements;
                    if (0 == tmpElemArr.length) {
                        result.title = srcData.surveyName;
                        result.error = "问卷包含空的板块(block:" + srcData.blocks[k + 1].blockId + "," + srcData.blocks[k + 1].description + ")，请联系问卷制作人删除该块！";
                        result.data = dataArray;
                        return result;
                    }
                    let tmpQstId = srcData.blocks[k + 1].blockElements[0].qstId;
                    if (undefined == tmpQstId) {
                        blockJumpDick[elements[i].qstId] = "无qstId";
                    } else {
                        blockJumpDick[elements[i].qstId] = tmpQstId.toString();
                    }
                }
            }

            if (0 == tmp.inner.length && ('单选' == tmp.type || '多选' == tmp.type || '排序选择' == tmp.type || '下拉选项' == tmp.type)) {
                tmp.type = '占位题';
            }
            tmp.srcType = elements[i].type + "_" + elements[i].questionType + "_" + elements[i].selector + "_" + elements[i].subSelector;
            tmp.srcQstData = elements[i];
            dataArray.push(tmp);

            logicDict4skip[elements[i].questionId] = elements[i].qstId;
            logicDict4display[elements[i].questionId] = counter; //elements[i].sortNo; // 
        }
    }

    //更新跳转逻辑题号
    updateSkipLogic(logicDict4skip, dataArray, blockJumpDick);
    //更新显示逻辑题号
    updateDisplayLogic(logicDict4display, dataArray);

    result.title = srcData.surveyName;
    result.data = dataArray;

    translate2newResult(result, resultNew);
    return resultNew; // return result; // 
};

console.log(JSON.stringify(getDataArr(param1)));//测试输出结果
